package com.bd.scm.module.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;

import lombok.extern.slf4j.Slf4j;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.springframework.util.ClassUtils;

/**
 * <h5>描述:缓存管理类</h5>
 * @author yufc
 */
@Slf4j
public class EhcacheUtil {

    private static final String CACHE_NAME = "bdCache";
    private static final String EHCACHE_CONFIG_NAME = "ehcache.xml";
    private static CacheManager cacheManager;

    static {
        String classesPath = getClassesPath();
        cacheManager =  CacheManager.create(classesPath + "config/" + EHCACHE_CONFIG_NAME);

//      EhcacheService.putObjectCache(CACHE_NAME, "key01", 1000);
//      EhcacheService.putObjectCache(CACHE_NAME, "key02", "abc");
//      EhcacheService.putObjectCache(CACHE_NAME, "key03", 3.1415);
//      EhcacheService.putObjectCache(CACHE_NAME, "key04", "哈哈");
//      EhcacheService.putObjectCache(CACHE_NAME, "key05", "{\"id\":100}");
    }

    /**
     * @功能描述：   添加一个缓存到指定的缓存中
     * @param cache_name 配置文件中缓存的name
     * @param key 键
     * @param value 缓存值
     */
    public synchronized static void put(String cache_name, String key, Object value) {
        Cache cache = getCache(cache_name);
        if (null != cache) {
            cache.remove(key);
            Element elem = new Element(key, value);
            cache.put(elem);
        }
    }

    public synchronized static void put(String key, Object value) {
        Cache cache = getCache(CACHE_NAME);
        if (null != cache) {
            cache.remove(key);
            Element elem = new Element(key, value);
            cache.put(elem);
        }
    }

    /**
     * @功能描述：   从指定的缓存中获取一个缓存数据的值
     * @param cache_name 配置文件中缓存的name
     * @param key 键
     * @return
     */
    public static String get(String cache_name, String key) {
        Cache cache = getCache(cache_name);
        if (null != cache) {
            Element element = cache.get(key);
            // isExpired(Element element) 检查缓存是否过期
            if (element != null && !cache.isExpired(element)) {
                return (String) element.getObjectValue();
            }
        }
        return "";
    }

    public static String get(String key) {
        Cache cache = getCache(CACHE_NAME);
        if (null != cache) {
            Element element = cache.get(key);
            // isExpired(Element element) 检查缓存是否过期
            if (element != null && !cache.isExpired(element)) {
                return (String) element.getObjectValue();
            }
        }
        return "";
    }

    /**
     * <h5>功能:清空指定缓存的所有信息</h5>
     * @param cache_name 配置文件中缓存的name
     */
    public static void remove(String cache_name){
        Cache cache = getCache(cache_name);
        cache.removeAll();
    }

    /**
     * <h5>功能:清空指定缓存的指定信息</h5>
     * @param cache_name 配置文件中缓存的name
     * @param key 键
     * @return boolean 是否移除成功
     */
    public static boolean remove(String cache_name, String key){
        Cache cache = getCache(cache_name);
        return cache.remove(key);
    }

    /**
     * 停止缓存管理器
     */
    public static void shutdown() {
        if (null!= cacheManager)
            cacheManager.shutdown();
    }

// ==================== private method ====================

    /**
     * @功能描述：   获取 classes 文件夹路径
     * @return classes绝对路径
     */
    private static String getClassesPath() {
//        String classesPath=Thread.currentThread().getContextClassLoader().getResource("").getPath();
        String classesPath= null;
        try {
            // 用URLDecoder解析空格等特殊字符，
            // Program Files获取后的路径是Program%20Files，导致路径识别失败
            classesPath = URLDecoder.decode(ClassUtils.getDefaultClassLoader().getResource("").getPath(),"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error(e.getMessage(), e);
        }
        return classesPath;
    }

    /**
     * @功能描述：   获取指定名称的缓存
     * @param cache_name 配置文件中缓存的name
     * @return Cache 缓存
     */
    private static Cache getCache(String cache_name) {
        return cacheManager.getCache(cache_name);
    }

    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getContextClassLoader().getResource("").getPath().substring(1));//user.dir指定了当前的路径

        EhcacheUtil.put(CACHE_NAME, "key01", 1000);
        EhcacheUtil.put(CACHE_NAME, "key02", "abc");
        EhcacheUtil.put(CACHE_NAME, "key03", 3.1415);
        EhcacheUtil.put(CACHE_NAME, "key04", "哈哈");
        EhcacheUtil.put(CACHE_NAME, "key05", "{\"id\":100}");

        EhcacheUtil.put(CACHE_NAME, "key04", "Hello World");

//      removeCache(CACHE_NAME);
//      removeCache(CACHE_NAME, "key05");
        Cache demoCache = cacheManager.getCache(CACHE_NAME);
        if (null != demoCache) {
            List<?> demoList=demoCache.getKeys();
            for(Object myKey:demoList){
                Element myElement=demoCache.get(myKey);
                System.out.println(myKey+"|"+myElement.getObjectValue());
            }
        }
        EhcacheUtil.put(CACHE_NAME, "key03", 3.1666);
        System.out.println("---------"+EhcacheUtil.get(CACHE_NAME, "key03"));

        System.exit(0);
    }
}